package com.mysgr.mod;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

import net.wimpi.modbus.ModbusCoupler;
import net.wimpi.modbus.facade.ModbusTCPMaster;
import net.wimpi.modbus.io.ModbusTCPTransaction;
import net.wimpi.modbus.msg.ModbusRequest;
import net.wimpi.modbus.msg.ModbusResponse;
import net.wimpi.modbus.msg.ReadCoilsRequest;
import net.wimpi.modbus.msg.ReadCoilsResponse;
import net.wimpi.modbus.msg.ReadInputDiscretesRequest;
import net.wimpi.modbus.msg.ReadInputDiscretesResponse;
import net.wimpi.modbus.msg.ReadInputRegistersRequest;
import net.wimpi.modbus.msg.ReadInputRegistersResponse;
import net.wimpi.modbus.msg.ReadMultipleRegistersRequest;
import net.wimpi.modbus.msg.ReadMultipleRegistersResponse;
import net.wimpi.modbus.msg.WriteCoilRequest;
import net.wimpi.modbus.msg.WriteMultipleRegistersRequest;
import net.wimpi.modbus.msg.WriteSingleRegisterRequest;
import net.wimpi.modbus.net.TCPMasterConnection;
import net.wimpi.modbus.procimg.InputRegister;
import net.wimpi.modbus.procimg.Register;
import org.apache.commons.lang.StringUtils;

import com.jfinal.kit.LogKit;

public class ModTcpM {

	public static String readByTCP(String ip, int port, String func, int ref, int quantity, Integer unitId)
			throws Exception {
		TCPMasterConnection con = null; // the connection
		ModbusTCPTransaction transaction = null; // the transaction
		// ModbusRequest req = null; // the request
		try {
			ModbusResponse res = null; // the response
			String data = null;
			InetAddress addr = InetAddress.getByName(ip);
			con = new TCPMasterConnection(addr);
			con.setPort(port);
			con.connect();
			transaction = new ModbusTCPTransaction(con);
			ModbusRequest request = getReadRequest(func, ref, quantity);
			// LogKit.info( "req=" + request );
			if (unitId != null)
				request.setUnitID(unitId);
			transaction.setRequest(request);
			transaction.execute();
			res = transaction.getResponse();
			return getResponseString(res);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;

	}

	public static ModbusRequest getReadRequest(String func, int ref, int quantity) {
		if (func.equals("05"))// 功能码：05
			return new WriteCoilRequest(ref, true);
		else if (func.equals("01"))// 功能码：01
			return new ReadCoilsRequest(ref, quantity);
		else if (func.equals("02"))// 功能码：02
			return new ReadInputDiscretesRequest(ref, quantity);
		else if (func.equals("04"))// 功能码：04
			return new ReadInputRegistersRequest(ref, quantity);
		else if (func.equals("03"))// 功能码：03
			return new ReadMultipleRegistersRequest(ref, quantity);
		else if (func.equals("06")) {
			Register r = ModbusCoupler.getReference().getProcessImageFactory().createRegister();
			// r.setValue( 420 );
			// 功能码：06
			return new WriteSingleRegisterRequest(0, r);
		} else if (func.equals("16"))// 功能码：16 return new
		{
			Register rr = ModbusCoupler.getReference().getProcessImageFactory().createRegister();
			rr.setValue(420);
			return new WriteMultipleRegistersRequest(0, new Register[] { rr });
		}

		return null;

	}

	private static String getResponseString(ModbusResponse res) {
		String data = null;
		if (res == null) {
			LogKit.info("TCP请求无返回值");
			return null;
		}
		LogKit.info("\nTransactionID=" + res.getTransactionID() + "\nProtocolID=" + res.getProtocolID()
				+ "\nDataLength=" + res.getDataLength() + "\nUnitID=" + res.getUnitID() + "\nFunctionCode="
				+ res.getFunctionCode() + "\nHexMessage=" + res.getHexMessage() + "");
		if (res instanceof ReadCoilsResponse) {
			ReadCoilsResponse t = (ReadCoilsResponse) res;
			LogKit.info("\ndata=" + t.getCoils().toString());
			//data = t.getCoils().toString();
			if( t.getCoils().getBit(0))
				data = "开";
			else
				data = "关";
		}
		if (res instanceof ReadInputDiscretesResponse) {
			ReadInputDiscretesResponse t = (ReadInputDiscretesResponse) res;
			LogKit.info("\ndata=" + t.getDiscretes().toString());
			data = t.getDiscretes().toString();
			System.out.println("t.getDiscretes():" + t.getDiscretes().toString());
		}
		if (res instanceof ReadInputRegistersResponse) {
			ReadInputRegistersResponse t = (ReadInputRegistersResponse) res;

			InputRegister[] s = t.getRegisters();
			List<Integer> valList = new ArrayList<Integer>();
			for (InputRegister ss : s) {
				// System.out.println( ss.getValue() );
				valList.add(ss.getValue());
			}
			data = "04-" + StringUtils.join(valList, "-");
			LogKit.info("\ndata=" + data);
		}
		if (res instanceof ReadMultipleRegistersResponse) {
			ReadMultipleRegistersResponse t = (ReadMultipleRegistersResponse) res;
			// LogKit.info( "\ndata=" + t.getRegisters().toString() );
			Register[] rlist = t.getRegisters();
			List<Integer> valList = new ArrayList<Integer>();
			for (Register r : rlist) {
				valList.add(r.getValue());
			}
			//data = "03-" + StringUtils.join(valList, "-");
			data =  StringUtils.join(valList, "-");
		//	data = String.valueOf(Float.parseFloat(data)/100);
			LogKit.info("\ndata=" + data);
		}
		return data;
	}

}
